<?php
// 应用公共文件

use app\common\model\Config;
use app\common\model\DictData;
use app\common\service\File;
use think\helper\Str;
use think\Response;

if (!function_exists('action_in_arr')) {
    /**
     * 检测一个方法是否在传递的数组内
     * @param array $arr
     * @return bool
     */
    function action_in_arr(array $arr = []): bool
    {
        $arr = is_array($arr) ? $arr : explode(',', $arr);
        if (!$arr) {
            return false;
        }
        $arr = array_map('strtolower', $arr);
        if (in_array(strtolower(request()->action()), $arr) || in_array('*', $arr)) {
            return true;
        }
        return false;
    }
}

if (!function_exists('get_sys_config')) {
    /**
     * 获取站点的系统配置，不传递参数则获取所有配置项
     * @param string $name   变量名
     * @param string $group  变量分组，传递此参数来获取某个分组的所有配置项
     * @param bool   $reduct 是否开启简洁模式，简洁模式下，获取多项配置时只返回配置的键值对
     * @return string | array
     */
    function get_sys_config(string $name = '', string $group = '', bool $reduct = true)
    {
        if ($name) {
            // 直接使用->value('value')不能使用到模型的类型格式化
            $config = Config::cache($name, null, Config::$cacheTag)->where('name', $name)->find();
            if ($config) $config = $config['value'];
        } else {
            if ($group) {
                $temp = Config::cache('group' . $group, null, Config::$cacheTag)->where('group', $group)->select()->toArray();
            } else {
                $temp = Config::cache('sys_config_all', null, Config::$cacheTag)->order('weigh desc')->select()->toArray();
            }
            if ($reduct) {
                $config = [];
                foreach ($temp as $item) {
                    $config[$item['name']] = $item['value'];
                }
            } else {
                $config = $temp;
            }
        }
        return $config;
    }
}

if (!function_exists('file_unit_to_byte')) {
    /**
     * 将一个文件单位转为字节
     * @param string $unit 将b、kb、m、mb、g、gb的单位转为 byte
     */
    function file_unit_to_byte(string $unit): int
    {
        preg_match('/([0-9\.]+)(\w+)/', $unit, $matches);
        if (!$matches) {
            return 0;
        }
        $typeDict = ['b' => 0, 'k' => 1, 'kb' => 1, 'm' => 2, 'mb' => 2, 'gb' => 3, 'g' => 3];
        return (int)($matches[1] * pow(1024, $typeDict[strtolower($matches[2])] ?? 0));
    }
}

if (!function_exists('convert')) {
    /**
     * 将字节集转为单位
     * @param $size
     * @return string
     */
    function convert($size): string
    {
        $unit=array('B','KB','MB','GB','TB','PB');
        return @round($size/pow(1024,($i=floor(log($size,1024)))),2).$unit[$i];
    }
}

if (!function_exists('create_guid')) {
    /**
     * 生成唯一UUID
     * @param string $namespace
     * @return string
     */
    function create_guid(string $namespace = ''): string
    {
        static $guid = '';
        $uid = uniqid("", true);
        $data = $namespace;
        $header = request()->header();
        $data .= implode('|', $header);
        $hash = strtoupper(hash('ripemd128', $uid . $guid . md5($data)));
        $guid = substr($hash, 0, 8) . substr($hash, 8, 4) . substr($hash, 12, 4) . substr($hash, 16, 4) . substr($hash, 20, 12);
        return Str::lower($guid);
    }
}

if (!function_exists('get_dict')) {
    /**
     * 获取字典数据
     * @param $code
     * @return array
     */
    function get_dict($code)
    {
         return DictData::cache("dict_{$code}", 120)
            ->where(['code' => $code, 'status' => 1])
            ->column(['label', 'value']);
    }
}

if (!function_exists('get_file_ext')) {
    /**
     * 获取文件后缀
     * @param $path
     * @return mixed|string
     */
    function get_file_ext($path): mixed
    {
        $info = pathinfo($path);
        return $info['extension'];
    }
}

if (!function_exists('getMimeType')) {
    /**
     * 获取文件类型
     * @param string $filename
     * @return string
     */
    function getMimeType(string $filename): string
    {
        $info = finfo_open(FILEINFO_MIME_TYPE);
        return finfo_file($info, $filename);
    }
}

if (!function_exists('build_suffix_svg')) {
    /**
     * 构建文件后缀的svg图片
     * @param string      $suffix     文件后缀
     * @param string|null $background 背景颜色，如：rgb(255,255,255)
     * @return string
     */
    function build_suffix_svg(string $suffix = 'file', string $background = null): string
    {
        $suffix = mb_substr(strtoupper($suffix), 0, 4);
        $total  = unpack('L', hash('adler32', $suffix, true))[1];
        $hue    = $total % 360;
        [$r, $g, $b] = hsv2rgb($hue / 360, 0.3, 0.9);

        $background = $background ?: "rgb($r,$g,$b)";

        return '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
            <path style="fill:#E2E5E7;" d="M128,0c-17.6,0-32,14.4-32,32v448c0,17.6,14.4,32,32,32h320c17.6,0,32-14.4,32-32V128L352,0H128z"/>
            <path style="fill:#B0B7BD;" d="M384,128h96L352,0v96C352,113.6,366.4,128,384,128z"/>
            <polygon style="fill:#CAD1D8;" points="480,224 384,128 480,128 "/>
            <path style="fill:' . $background . ';" d="M416,416c0,8.8-7.2,16-16,16H48c-8.8,0-16-7.2-16-16V256c0-8.8,7.2-16,16-16h352c8.8,0,16,7.2,16,16 V416z"/>
            <path style="fill:#CAD1D8;" d="M400,432H96v16h304c8.8,0,16-7.2,16-16v-16C416,424.8,408.8,432,400,432z"/>
            <g><text><tspan x="220" y="380" font-size="124" font-family="Verdana, Helvetica, Arial, sans-serif" fill="white" text-anchor="middle">' . $suffix . '</tspan></text></g>
        </svg>';
    }
}

if (!function_exists('hsv2rgb')) {
    function hsv2rgb($h, $s, $v): array
    {
        $r = $g = $b = 0;

        $i = floor($h * 6);
        $f = $h * 6 - $i;
        $p = $v * (1 - $s);
        $q = $v * (1 - $f * $s);
        $t = $v * (1 - (1 - $f) * $s);

        switch ($i % 6) {
            case 0:
                $r = $v;
                $g = $t;
                $b = $p;
                break;
            case 1:
                $r = $q;
                $g = $v;
                $b = $p;
                break;
            case 2:
                $r = $p;
                $g = $v;
                $b = $t;
                break;
            case 3:
                $r = $p;
                $g = $q;
                $b = $v;
                break;
            case 4:
                $r = $t;
                $g = $p;
                $b = $v;
                break;
            case 5:
                $r = $v;
                $g = $p;
                $b = $q;
                break;
        }

        return [
            floor($r * 255),
            floor($g * 255),
            floor($b * 255)
        ];
    }
}

if (!function_exists('downloads')) {
    /**
     * 获取\think\response\Download对象实例
     * @param string $filename 要下载的文件
     * @param string $name 显示文件名
     * @param bool $content 是否为内容
     * @param int $expire 有效期（秒）
     * @return File
     */
    function downloads(string $filename, string $name = '', bool $content = false, int $expire = 180): File
    {
        return Response::create($filename, '\\app\\common\\service\\File')->name($name)->isContent($content)->expire($expire);
    }
}

if (!function_exists('getVideoCover')) {
    /**
     * 获取视频封面
     * @param string $video
     * @return array|bool|string
     */
    function getVideoCover(string $video): array|bool|string
    {
        if (!is_file($video)) {
            return false;
        }
        $ext = pathinfo($video, PATHINFO_EXTENSION);
        $path = str_replace($ext, 'png', $video);
        if (is_file($path)) {
            return $path;
        }
        $command = "ffmpeg -i {$video} -ss 00:00:01 -frames:v 1 {$path}";
        shell_exec($command);
        if (is_file($path)) {
            return $path;
        }
        return false;
    }
}